
#include "simple_button_polling.h"

union _ButtonFlagByte poll_button_flag;

// 集成消抖功能的按键轮询函数
void poll_button(void) {
    static uint8_t scan_buffer = 0xff;  // 按键是低电平有效，所以初始状态缓冲区全为1
    static uint8_t long_press_counter = 0;

#ifndef _BUTTON_POLL_DISABLE_DOUBLE_PRESS
    static uint8_t double_press_counter = 0;
#endif

    scan_buffer <<= 1;
    if (_BUTTON_POLL_GET_PIN()) {
        scan_buffer |= 0x01;
    }

    if (!poll_button_flag.bits._pressed) {
        if ((scan_buffer & _BUTTON_POLL_FILTER_MASK) == 0) {  // 连续6 次低电平，表示按键确实按下了
            poll_button_flag.bits._pressed = 1;
            poll_button_flag.bits.button_pressed = 1;         // 函数外面的标志位由主程序检查，使用一次后清零，以免重复触发

            // 启动长按计数器
            long_press_counter = _BUTTON_LONG_PRESS_THRESHOLD;

#ifndef _BUTTON_POLL_DISABLE_DOUBLE_PRESS

            // 第二次按下发生在双击等待时间内，触发双击事件
            if (double_press_counter != 0) {
                poll_button_flag.bits.button_double_pressed = 1;
                double_press_counter = 0;
            }
        }
        else {  // 否则按键还在抬起状态，更新双击等待计数器，直到计数器归零
            if (double_press_counter != 0) {
                --double_press_counter;
            }
#endif
        }
    }
    else {
        if (((~scan_buffer) & _BUTTON_POLL_FILTER_MASK) == 0) {  // 连续6 次高电平，表示按键抬起。所以一次press 至少会持续8 次扫描
            poll_button_flag.bits._pressed = 0;

#ifndef _BUTTON_POLL_DISABLE_DOUBLE_PRESS
            // 启动双击等待计数器，同时清零双击超时事件
            double_press_counter = _BUTTON_DOUBLE_PRESS_THRESHOLD;
            poll_button_flag.bits.button_double_press_timeout = 0;
#endif

            // 长按后抬起，忽略clicked 事件
            if (long_press_counter == 0) {
                poll_button_flag.bits.button_long_press_released = 1;
            }
            else {
                poll_button_flag.bits.button_clicked = 1;
            }

            // 清零长按计数器
            long_press_counter = 0;
            poll_button_flag.bits.button_released = 1;
        }
        else {  //  否则按键尚未抬起，更新长按计数器和长按事件
            if (long_press_counter != 0) {
                --(long_press_counter);

                if (long_press_counter == 0) {
                    poll_button_flag.bits.button_long_pressed = 1;
                }
            }
        }
    }
}